#include "StdAfx.hpp"
#include "Parser.hpp"
#include "Data.hpp"
#include "Tokenizer2.hpp"
#include "CharReader2.hpp"
#include "Context.hpp"


int main(int argc, char **argv)
{
	try
	{
		ALL_EXCEPTIONS_TRY;

		string doc;
		{
			if (argc == 2)
				LoadStringFromFile(argv[1], &doc);
			else
			{
				string line;
				while (getline(std::cin, line))
				{
					doc += line;
					doc += '\n';
				}
			}
		}

		////// Test module

		shared_ptr<Module> module;
		{
			CharReader2 cr(doc);
			Tokenizer2 tok(cr);
			module.reset(ParseModule(tok));
			tok.AssertEOF();
		}

		module->Preprocess();
		module->Exec();

		////// Test code block

		/*CodeBlockPtr codeBlock;
		{
			CharReader2 cr(doc);
			Tokenizer2 tok(cr);
			codeBlock.reset(ParseCodeBlock(tok));
			tok.AssertEOF();
		}

		codeBlock->Preprocess();
		codeBlock->Exec();*/

		/*shared_ptr<Expression> mainExp;
		{
			CharReader2 cr(doc);
			Tokenizer2 tok(cr);
			mainExp.reset(ParseExpressionA(tok));
			tok.AssertEOF();
		}

		mainExp->Preprocess();

		mainExp->PrintDebug(0);

		switch (mainExp->Type)
		{
		case TYPE_INT:
			{
				int val;
				mainExp->Eval(&val);
				std::cout << "Result(int): " << val << std::endl;
			}
			break;
		case TYPE_FLOAT:
			{
				float val;
				mainExp->Eval(&val);
				std::cout << "Result(float): " << val << std::endl;
			}
			break;
		case TYPE_BOOL:
			{
				bool val;
				mainExp->Eval(&val);
				std::cout << "Result(bool): " << (val ? "true" : "false") << std::endl;
			}
			break;
		case TYPE_CHAR:
			{
				char val;
				mainExp->Eval(&val);
				std::cout << "Result(char): " << (unsigned)(unsigned char)val << std::endl;
			}
			break;
		case TYPE_STRING:
			{
				string val;
				mainExp->Eval(&val);
				std::cout << "Result(string): \"" << val << "\"" << std::endl;
			}
			break;
		default:
			assert(0);
		}*/

		return 0;
		ALL_EXCEPTIONS_CATCH;
	}
	catch (const Error &e)
	{
		string msg;
		e.GetMessage_(&msg);
		std::cout << "ERROR:\n";
		std::cout << msg << std::endl;
		return -1;
	}
}
